<template>
  <div class="ball-container">
    <div v-for="(ball, index) in balls" :key="index">
      <transition name="drop" @before-enter="beforeDrop" @enter="dropping" @after-enter="afterDrop">
        <div v-show="ball.show" class="ball">
          <div class="inner inner-hook"></div>
        </div>
      </transition>
    </div>
  </div>
</template>
<script>
import {eventBus} from '../eventBus';
export default {
  data() {
    return {
      balls: [
        {
          show: false
        },

        {
          show: false
        },

        {
          show: false
        },

        {
          show: false
        },

        {
          show: false
        }
      ],
      dropBalls: []
    };
  },
  methods: {
    drop(el) {
      for (let i = 0; i < this.balls.length; i++) {
        let ball = this.balls[i];
        if (ball.show === false) {
          ball.show = true;
          ball.el = el; //设置小球的el属性为一个dom对象
          this.dropBalls.push(ball);
          return; //此处return终结函数,这意味着每次触发事件,dropBalls内只增加一个ball
        }
      }
    },
    beforeDrop(el) {
      let count = this.balls.length;
      while (count--) {
        let ball = this.balls[count];
        if (ball.show) {
          let rect = ball.el.getBoundingClientRect(); //获取元素的位置
          let x = rect.left - 32; //小球掉落X轴起点
          let y = -(window.innerHeight - rect.top - 22); //小球掉落Y轴起点,向下为负
          el.style.display = "";
          el.style.webkitTransform = `translate3d(0, ${y}px,0)`; /* Safari 和 Chrome */
          el.style.transform = `translate3d(0, ${y}px,0)`; //旋转div元素
          // 处理内层动画
          let inner = el.getElementsByClassName("inner-hook")[0];
          inner.style.webkitTransform = `translate3d(${x}px, 0, 0)`;
          inner.style.transform = `translate3d(${x}px,0,0)`;
        }
      }
    },
    dropping(el, done) {
      //关闭ESlint语法监测，因为ES6语言规范会让被申明却未被调用的变量报错
      /* eslint-disable no-unused-vars */
      let rf = el.offsetHeight; //申明rf是为了触发浏览器的重排
      this.$nextTick(() => {
        //修改数据之后立即使用这个方法，获取更新后的 DOM。
        el.style.webkitTransform =
          "translate3d(0, 0, 0)"; /* Safari 和 Chrome */
        el.style.transform = "translate3d(0, 0, 0)"; //旋转div元素
        let inner = el.getElementsByClassName("inner-hook")[0];
        inner.style.webkitTransform = "translate3d(0, 0, 0)";
        inner.style.transform = "translate3d(0, 0, 0)";
        el.addEventListener("transitionend", done); //Vue为了知道过渡的完成，否则无法进入到afterEnter中
      });
    },
    afterDrop(el) {
      let ball = this.dropBalls.shift(); //把数组的第一个元素从其中删除，并返回第一个元素的值。
      if (ball) {
        ball.show = false;
        el.style.display = "none"; //隐藏小球
      }
    }
  },
  created() {
    eventBus.$on("add-cart",this.drop);
  }
};
</script>

<style lang="scss" scoped>
.ball-container {
  .ball {
    position: fixed;
    left: 32px;
    bottom: 22px;
    z-index: 200;
    transition: all 0.4s cubic-bezier(0.49, -0.29, 0.75, 0.14); //贝塞尔曲线
    .inner {
      width: 16px;
      height: 16px;
      border-radius: 50%;
      background: #ff5355;
      transition: all 0.4s linear;
    }
  }
}
</style>
